# -*-coding:utf-8-*-
import pandas as pd

"""1.merge合并（相当于sql中的join）
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, 
         left_index=False, right_index=False, sort=False, suffixes=('_x','_y'))
    以两个dataframe对象的一个或多个列作为连接键进行连接合并
    -left：左侧DataFrame对象
    -right：右侧DataFrame对象
    -on：单个列名或列名列表，以此作为连接键进行连接。列名必须在两个df中同时存在（不同的话要使用left_on和right_on指定）
    -left_on：指定左侧DataFrame中的哪些列作为连接键
    -right_on：指定右侧DataFrame中的哪些列作为连接键
    -left_index：如果为True，则使用左侧DataFrame中的行索引作为其连接键
    -right_index：与左侧DataFrame的left_index具有相同的用法
    -how：inner(内连接)、left(左外连接)、right(右外连接)、outer(全外连接)，默认为inner
    -sort：按照字典顺序通过连接键对结果DataFrame进行排序
    -suffixes: 用于重叠列的字符串后缀元组。 默认为('_x','_y')
>>> df_merge1
     编号  语文   数学   英语  体育
0  mr001   110   105    99    34
1  mr001   110   105    99    36
2  mr002   105    88   115    39
>>> df_merge2
     编号   语文  数学   英语   体育
0  mr001   110   105    99  34.0
1  mr001   110   105    99  36.0
2  mr002   105    88   115  39.0
3  mr003   109   120   130   NaN
>>> df_merge3
     编号  语文   数学  英语   序号   体育
0  mr001   110   105    99  mr001    34
1  mr002   105    88   115  mr002    39
>>> df_merge4
     编号  体育   序号
0  mr001    34  mr001
1  mr002    39  mr002
"""
pd.set_option('display.unicode.east_asian_width', True)
df1 = pd.DataFrame([['mr001', 110, 105, 99],
                    ['mr002', 105, 88, 115],
                    ['mr003', 109, 120, 130]], columns=['编号', '语文', '数学', '英语'])
df2 = pd.DataFrame([['mr001', 34],
                    ['mr001', 36],
                    ['mr002', 39]], columns=['编号', '体育'])
df3 = pd.DataFrame([['mr001', 34],
                    ['mr002', 39]], columns=['序号', '体育'])
df_merge1 = pd.merge(df1, df2, on='编号')  # 内连接合并两张表（注意两个df连接键值一对多、多对一和多对多的情况）
df_merge2 = pd.merge(df1, df2, on='编号', how='left')  # 左连接合并两张表
df_merge3 = pd.merge(df1, df3, left_on='编号', right_on='序号')  # 分别指定两张表的连接键合并两张表
df_merge4 = pd.merge(df2, df3)  # 不指定on时以两个df所有的同名列作为连接键。两个df列名完全一样且为内连接时相当于求两者相同的行（即交集）

"""concat合并
pd.concat(objs, axis=0, join="outer", ignore_index=False, keys=None, levels=None, 
          names=None, verify_integrity=False, sort=False, copy=True)
    轴向连接。就是单纯地把两个表拼在一起，这个过程也被称作绑定或堆叠，合并时不会删除拼接方向上的重复项
    -objs：要连接的df、series的序列或映射
    -axis：要连接的轴。0：横向连接。1：纵向连接
    -join：如何处理其他轴上的索引，值只能为inner或outer
    -ignore_index：如果为True，将连接轴上的索引重置为0、1...n-1。
    -keys：使用传递的键作为最外层构建层次索引（如果为多索引，类型应为元组）
    -names：生成的分层索引中级别的名称
    -verify_integrity：检查新的连接轴是否包含重复项
    -sort：如果“join”为“outer”时未对齐，则对非连接轴进行排序。这在 ``join='inner'`` 时无效，它已经保留了非连接轴的顺序
>>> df_concat1
     编号  体育    序号   体育
0  mr001    34  mr001    34
1  mr001    36  mr002    39
>>> df_concat2
     编号  体育    序号   体育
0  mr001    34  mr001  34.0
1  mr001    36  mr002  39.0
2  mr002    39    NaN   NaN
>>> df_concat3
     编号   语文    数学   英语   体育
0  mr001  110.0  105.0   99.0   NaN
1  mr002  105.0   88.0  115.0   NaN
2  mr003  109.0  120.0  130.0   NaN
3  mr001    NaN    NaN    NaN  34.0
4  mr001    NaN    NaN    NaN  36.0
5  mr002    NaN    NaN    NaN  39.0
>>> df_concat4
        序号  体育
t1 0  mr001    34
   1  mr002    39
t2 0  mr001    34
   1  mr002    39
"""
df_concat1 = pd.concat([df2, df3], axis=1, join='inner')  # 横向连接两表，只保留两者索引相同的行
df_concat2 = pd.concat([df2, df3], axis=1)  # 横向连接两表，两者的行列都保留（空缺的值填充为Nan）
df_concat3 = pd.concat([df1, df2], ignore_index=True)  # 纵向连接两表，两者的行列都保留，重置索引
df_concat4 = pd.concat([df3, df3], keys=('t1', 't2'))  # 纵向连接两表，添加外层索引